<?php

namespace App\Remote\MeiTuan;

use Closure;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Symfony\Component\HttpFoundation\Response as ResponseAlias;

abstract class Remote extends \App\Remote\Remote
{
    /**
     * @return HandlerStack
     */
    public static function getHandlerStack(): HandlerStack
    {
        //获取基础中间件
        $handleStack = parent::getHandlerStack();
        //增加重试中间件
        $handleStack->before("logMiddleware",
            Middleware::retry(function (
                int $retryTimes,
                Request $request,
                Response $response = null,
                \Exception $exception = null
            ) {
                if ($retryTimes >= 5) {
                    return false;
                }

                if ($exception instanceof ConnectException) {
                    return true;
                }

                if (!is_null($response)) {
                    $responseContents = $response->getBody()->getContents();
                    $response->getBody()->rewind();
                    if (empty($responseContents)) {
                        return true;
                    }
                }
                return false;
            }, function () {
                return 1000 * 5;
            }), "retryMiddleware");

        return $handleStack;
    }

    public static function registerResponseHandle(): Closure
    {
        return function () {
            list($responseHttpCode, $responseContent) = func_get_args();
            if ($responseHttpCode != ResponseAlias::HTTP_OK) {
                throw new \Exception($responseContent);
            }

            if (isJson($responseContent)) {
                $responseArr = jsonToArr($responseContent);
                if ($responseArr["code"] != 0) {
                    throw new \Exception($responseArr["msg"]);
                }
                return $responseArr["data"];
            }

            throw new \Exception("[ $responseHttpCode ]-[ $responseContent ]");
        };
    }
}
